package com.ynding.cloud.auth.authentication.controller;

import com.ynding.cloud.auth.api.authentication.model.bo.UserInfo;
import com.ynding.cloud.auth.authentication.config.security.service.UserDetailsServiceImpl;
import com.ynding.cloud.auth.authentication.service.IRegLoginService;
import com.ynding.cloud.auth.authentication.utils.Md5Util;
import com.ynding.cloud.common.model.bo.AuthConstants;
import com.ynding.cloud.common.model.bo.ResponseBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author ynding
 */
@Slf4j
@RestController
@Api(value = "RegLogin", tags = {"登录注册-Controller"})
@RequiredArgsConstructor
public class RegLoginController {

    private final UserDetailsServiceImpl userDetailsService;
    private final RedisTemplate<String, String> redisTemplate;
    private final AuthenticationManager authenticationManager;
    private final RestTemplate restTemplate;
    private final LoadBalancerClient loadBalancerClient;

    private final IRegLoginService regLoginService;


    @GetMapping("/login_p")
    public ModelAndView login(ModelAndView m) {

        m.setViewName("login_p");
        return m;
    }

    @PostMapping("/login")
    @ApiOperation(value = "登录", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户", required = true, dataTypeClass = UserInfo.class),
    })
    public ResponseBean refreshAndGetAuthenticationToken(
            @RequestBody UserInfo user) throws AuthenticationException {

        String username = user.getUsername();
        String password = user.getPassword();
        return ResponseBean.ok(regLoginService.getToken(username,password));
    }

    @PostMapping("/register")
    @ApiOperation(value = "注册", produces = "application/json")
    @ApiImplicitParam(name = "user", value = "用户", required = true, dataType = "UserInfo", dataTypeClass = UserInfo.class)
    public ResponseBean register(
            @RequestBody UserInfo user) throws AuthenticationException {

        String username = user.getUsername();
        String password = user.getPassword();
        return regLoginService.userReg(username, password);
    }


    /**
     * 登陆与授权.
     *
     * @param username .
     * @param password .
     * @return
     */
    private String generateToken(String username, String password) {
        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);
        // Perform the security
        final Authentication authentication = authenticationManager.authenticate(upToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        // Reload password post-security so we can generate token
        final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        // 持久化的redis
        String token = AuthConstants.JWT_TOKEN_PREFIX + Md5Util.stringToMD5(userDetails.getUsername());
        redisTemplate.opsForValue().set(token, userDetails.getUsername());
        return token;
    }


}
